/*
 * $Id: PolisAclTestCase.java 27 2007-04-13 01:02:48Z aaron.day $
 */
package org.crazydays.core.data;


import java.util.Iterator;

import org.hibernate.Session;
import org.hibernate.HibernateException;

import junit.framework.TestCase;

import org.crazydays.hibernate.HibernateUtil;

/**
 * PolisUserAclCase
 */
public class PolisAclTestCase
	extends TestCase
{
	/**
	 * Test allow.
	 * 
	 * @param session Session
	 * @param acl Acl
	 * @param groupName Group name
	 * @param rightName Right name
	 * @return Allow
	 * @throws HibernateException
	 */
	protected boolean testAllowGroup(Session session, PolisAcl acl,
			String groupName, String rightName)
	{
		if (session == null) {
			throw new IllegalArgumentException("session == null");
		}
		if (acl == null) {
			throw new IllegalArgumentException("acl == null");
		}
		if (groupName == null) {
			throw new IllegalArgumentException("groupName == null");
		}
		if (rightName == null) {
			throw new IllegalArgumentException("rightName == null");
		}

		PolisGroup group = (PolisGroup) HibernateUtil
				.loadPolisDataByName(session, PolisGroup.class,
						groupName);
		assertNotNull("group == null", group);

		PolisRight right = (PolisRight) HibernateUtil
				.loadPolisDataByName(session, PolisRight.class,
						rightName);
		assertNotNull("right == null", right);

		return acl.allow(group, right);
	}

	/**
	 * Test allow.
	 * 
	 * @param session Session
	 * @param acl Acl
	 * @param userName User name
	 * @param rightName Right name
	 * @return Allow
	 * @throws HibernateException
	 */
	protected boolean testAllowUser(Session session, PolisAcl acl,
			String userName, String rightName)
		throws HibernateException
	{
		if (session == null) {
			throw new IllegalArgumentException("session == null");
		}
		if (acl == null) {
			throw new IllegalArgumentException("acl == null");
		}
		if (userName == null) {
			throw new IllegalArgumentException("userName == null");
		}
		if (rightName == null) {
			throw new IllegalArgumentException("rightName == null");
		}

		PolisUser user = (PolisUser) HibernateUtil.loadPolisDataByName(
				session, PolisUser.class, userName);
		assertNotNull("user == null", user);

		PolisRight right = (PolisRight) HibernateUtil
				.loadPolisDataByName(session, PolisRight.class,
						rightName);
		assertNotNull("right == null", right);

		return acl.allow(user, right);
	}

	/**
	 * Test guest.
	 */
	public void testGuest()
	{
		Session session = HibernateUtil.getSession();
		try {
			PolisAcl acl = (PolisAcl) HibernateUtil
					.loadPolisDataByName(session,
							PolisAcl.class, "Guest");

			assertNotNull("acl == null", acl);

			// user
			PolisUser user = acl.getUser();
			assertNotNull("user == null", user);
			assertEquals("user.name != Admin", user.getName(),
					"Admin");

			// groups
			assertNotNull("acl.groups == null", acl.getGroups());
			assertEquals("acl.groups.size != 3", acl.getGroups()
					.size(), 3);

			Iterator<PolisGroup> groups = acl.getGroups()
					.iterator();
			while (groups.hasNext()) {
				PolisGroup group = groups.next();

				if (group.getName().equals("Guest")) {
					continue;
				}
				if (group.getName().equals("Admin")) {
					continue;
				}
				if (group.getName().equals("User")) {
					continue;
				}
				fail("acl.groups unknown group: "
						+ group.getName());
			}

			// aclGroups
			assertNotNull("acl.aclGroups == null", acl
					.getAclGroups());
			assertEquals("acl.aclGroups.size != 8", acl
					.getAclGroups().size(), 8);

			boolean allow = false;

			// group guest
			allow = testAllowGroup(session, acl, "Guest", "Admin");
			assertFalse("allowGroup(Guest,Admin) == true", allow);
			allow = testAllowGroup(session, acl, "Guest", "Execute");
			assertTrue("allowGroup(Guest,Execute) == false", allow);
			allow = testAllowGroup(session, acl, "Guest", "Read");
			assertTrue("allowGroup(Guest,Read) == false", allow);
			allow = testAllowGroup(session, acl, "Guest", "Write");
			assertFalse("allowGroup(Guest,Write) == true", allow);

			// group admin
			allow = testAllowGroup(session, acl, "Admin", "Admin");
			assertTrue("allowGroup(Admin,Admin) == false", allow);
			allow = testAllowGroup(session, acl, "Admin", "Execute");
			assertTrue("allowGroup(Admin,Execute) == false", allow);
			allow = testAllowGroup(session, acl, "Admin", "Read");
			assertTrue("allowGroup(Admin,Read) == false", allow);
			allow = testAllowGroup(session, acl, "Admin", "Write");
			assertTrue("allowGroup(Admin,Write) == false", allow);

			// group user
			allow = testAllowGroup(session, acl, "User", "Admin");
			assertFalse("allowGroup(User,Admin) == true", allow);
			allow = testAllowGroup(session, acl, "User", "Execute");
			assertTrue("allowGroup(User,Execute) == false", allow);
			allow = testAllowGroup(session, acl, "User", "Read");
			assertTrue("allowGroup(User,Read) == false", allow);
			allow = testAllowGroup(session, acl, "User", "Write");
			assertFalse("allowGroup(User,Write) == true", allow);

			// user guest
			allow = testAllowUser(session, acl, "Guest", "Admin");
			assertFalse("allowUser(Guest,Admin) == true", allow);
			allow = testAllowUser(session, acl, "Guest", "Execute");
			assertTrue("allowUser(Guest,Execute) == false", allow);
			allow = testAllowUser(session, acl, "Guest", "Read");
			assertTrue("allowUser(Guest,Read) == false", allow);
			allow = testAllowUser(session, acl, "Guest", "Write");
			assertFalse("allowUser(Guest,Write) == true", allow);

			// user admin
			allow = testAllowUser(session, acl, "Admin", "Admin");
			assertTrue("allowUser(Admin,Admin) == false", allow);
			allow = testAllowUser(session, acl, "Admin", "Execute");
			assertTrue("allowUser(Admin,Execute) == false", allow);
			allow = testAllowUser(session, acl, "Admin", "Read");
			assertTrue("allowUser(Admin,Read) == false", allow);
			allow = testAllowUser(session, acl, "Admin", "Write");
			assertTrue("allowUser(Admin,Write) == false", allow);
		} catch (HibernateException e) {
			fail("HibernateException: " + e.getMessage());
		} finally {
			if (session != null) {
				session.close();
			}
		}
	}

	/**
	 * Test admin.
	 */
	public void testAdmin()
	{
		Session session = HibernateUtil.getSession();
		try {
			PolisAcl acl = (PolisAcl) HibernateUtil
					.loadPolisDataByName(session,
							PolisAcl.class, "Admin");

			assertNotNull("acl == null", acl);

			// user
			PolisUser user = acl.getUser();
			assertNotNull("user == null", user);
			assertEquals("user.name != Admin", user.getName(),
					"Admin");

			// groups
			assertNotNull("acl.groups == null", acl.getGroups());
			assertEquals("acl.groups.size != 1", acl.getGroups()
					.size(), 1);

			Iterator<PolisGroup> groups = acl.getGroups()
					.iterator();
			while (groups.hasNext()) {
				PolisGroup group = groups.next();

				if (group.getName().equals("Admin")) {
					continue;
				}
				fail("acl.groups unknown group: "
						+ group.getName());
			}

			// aclGroups
			assertNotNull("acl.aclGroups == null", acl
					.getAclGroups());
			assertEquals("acl.aclGroups.size != 4", acl
					.getAclGroups().size(), 4);

			boolean allow = false;

			// group guest
			allow = testAllowGroup(session, acl, "Guest", "Admin");
			assertFalse("allowGroup(Guest,Admin) == true", allow);
			allow = testAllowGroup(session, acl, "Guest", "Execute");
			assertFalse("allowGroup(Guest,Execute) == true", allow);
			allow = testAllowGroup(session, acl, "Guest", "Read");
			assertFalse("allowGroup(Guest,Read) == true", allow);
			allow = testAllowGroup(session, acl, "Guest", "Write");
			assertFalse("allowGroup(Guest,Write) == true", allow);

			// group admin
			allow = testAllowGroup(session, acl, "Admin", "Admin");
			assertTrue("allowGroup(Admin,Admin) == false", allow);
			allow = testAllowGroup(session, acl, "Admin", "Execute");
			assertTrue("allowGroup(Admin,Execute) == false", allow);
			allow = testAllowGroup(session, acl, "Admin", "Read");
			assertTrue("allowGroup(Admin,Read) == false", allow);
			allow = testAllowGroup(session, acl, "Admin", "Write");
			assertTrue("allowGroup(Admin,Write) == false", allow);

			// group user
			allow = testAllowGroup(session, acl, "User", "Admin");
			assertFalse("allowGroup(User,Admin) == true", allow);
			allow = testAllowGroup(session, acl, "User", "Execute");
			assertFalse("allowGroup(User,Execute) == true", allow);
			allow = testAllowGroup(session, acl, "User", "Read");
			assertFalse("allowGroup(User,Read) == true", allow);
			allow = testAllowGroup(session, acl, "User", "Write");
			assertFalse("allowGroup(User,Write) == true", allow);
		} catch (HibernateException e) {
			fail("HibernateException: " + e.getMessage());
		} finally {
			if (session != null) {
				session.close();
			}
		}
	}

	/**
	 * Test user.
	 */
	public void testUser()
	{
		Session session = HibernateUtil.getSession();
		try {
			PolisAcl acl = (PolisAcl) HibernateUtil
					.loadPolisDataByName(session,
							PolisAcl.class, "User");

			assertNotNull("acl == null", acl);

			// user
			PolisUser user = acl.getUser();
			assertNotNull("user == null", user);
			assertEquals("user.name != Admin", user.getName(),
					"Admin");

			// groups
			assertNotNull("acl.groups == null", acl.getGroups());
			assertEquals("acl.groups.size != 2", acl.getGroups()
					.size(), 2);

			Iterator<PolisGroup> groups = acl.getGroups()
					.iterator();
			while (groups.hasNext()) {
				PolisGroup group = groups.next();

				if (group.getName().equals("Admin")) {
					continue;
				}
				if (group.getName().equals("User")) {
					continue;
				}
				fail("acl.groups unknown group: "
						+ group.getName());
			}

			// aclGroups
			assertNotNull("acl.aclGroups == null", acl
					.getAclGroups());
			assertEquals("acl.aclGroups.size != 7", acl
					.getAclGroups().size(), 7);

			boolean allow = false;

			// group guest
			allow = testAllowGroup(session, acl, "Guest", "Admin");
			assertFalse("allowGroup(Guest,Admin) == true", allow);
			allow = testAllowGroup(session, acl, "Guest", "Execute");
			assertFalse("allowGroup(Guest,Execute) == true", allow);
			allow = testAllowGroup(session, acl, "Guest", "Read");
			assertFalse("allowGroup(Guest,Read) == true", allow);
			allow = testAllowGroup(session, acl, "Guest", "Write");
			assertFalse("allowGroup(Guest,Write) == true", allow);

			// group admin
			allow = testAllowGroup(session, acl, "Admin", "Admin");
			assertTrue("allowGroup(Admin,Admin) == false", allow);
			allow = testAllowGroup(session, acl, "Admin", "Execute");
			assertTrue("allowGroup(Admin,Execute) == false", allow);
			allow = testAllowGroup(session, acl, "Admin", "Read");
			assertTrue("allowGroup(Admin,Read) == false", allow);
			allow = testAllowGroup(session, acl, "Admin", "Write");
			assertTrue("allowGroup(Admin,Write) == false", allow);

			// group user
			allow = testAllowGroup(session, acl, "User", "Admin");
			assertFalse("allowGroup(User,Admin) == true", allow);
			allow = testAllowGroup(session, acl, "User", "Execute");
			assertTrue("allowGroup(User,Execute) == false", allow);
			allow = testAllowGroup(session, acl, "User", "Read");
			assertTrue("allowGroup(User,Read) == false", allow);
			allow = testAllowGroup(session, acl, "User", "Write");
			assertTrue("allowGroup(User,Write) == false", allow);
		} catch (HibernateException e) {
			fail("HibernateException: " + e.getMessage());
		} finally {
			if (session != null) {
				session.close();
			}
		}
	}
}
